import EventEmitter from 'node:events'
import net from 'node:net'

import {TelnetInterface} from 'tui-lib/util/interfaces'

import setupClient from './client.js'

export default class TelnetServer extends EventEmitter {
  constructor(backend) {
    super()

    this.backend = backend
    this.server = new net.Server(socket => this.handleConnection(socket))
    this.sockets = []
  }

  listen(port) {
    this.server.listen(port)
  }

  async handleConnection(socket) {
    const telnetInterface = new TelnetInterface(socket)
    const { appElement, cleanTerminal, flushable } = await setupClient({
      backend: this.backend,
      writable: socket,
      screenInterface: telnetInterface,
      appConfig: {
        canControlPlayback: false,
        canControlQueue: true,
        canControlQueuePlayers: false,
        canProcessMetadata: false,
        canSuspend: false,
        showTabberPane: true,
        stopPlayingUponQuit: false,
        menubarColor: 2
      }
    })

    appElement.attachAsServerClient(this)

    let closed = false

    const quit = (msg = 'See you!') => {
      cleanTerminal()
      telnetInterface.cleanTelnetOptions()
      socket.write('\r' + msg + '\r\n')
      socket.end()
      flushable.end()
      closed = true
      this.sockets.splice(this.sockets.indexOf(socket), 1)
    }

    appElement.on('quitRequested', quit)

    socket.on('close', () => {
      if (!closed) {
        flushable.end()
        closed = true
        this.sockets.splice(this.sockets.indexOf(socket), 1)
      }
      this.emit('left', socket)
    })

    socket.quit = quit
    this.sockets.push(socket)
    this.emit('joined', socket)
  }

  disconnectAllSockets(msg) {
    while (this.sockets.length) {
      this.sockets[0].quit(msg)
    }
  }
}
